package com.chenguo.gulimall.search.thread;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class CompletableFutureTest {
    public static ExecutorService executor = Executors.newFixedThreadPool(10);

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        System.out.println("main......start.....");

        //用自己线程池
        //         CompletableFuture<Void> future = CompletableFuture.runAsync(() -> {
        //             System.out.println("当前线程：" + Thread.currentThread().getId());
        //             int i = 10 / 2;
        //             System.out.println("运行结果：" + i);
        //         }, executor);


         /*
            runAsync    都是没有返回结果的
            supplyAsync 都是可以获取返回结果的

          */
        /**
         *
         *
         * 方法完成后的处理  有返回值
         */
//         CompletableFuture<Integer> future1 =
//                 CompletableFuture.supplyAsync(() -> {
//             System.out.println("当前线程：" + Thread.currentThread().getId());
//             int i = 10 / 0;
//             System.out.println("运行结果：" + i);
//             return i;
//         }, executor).whenComplete((res,exception) -> {
//             //res 结果  exception  异常
//             //虽然能得到异常信息，但是没法修改返回数据
//             System.out.println("异步任务成功完成了...结果是：" + res + "异常是：" + exception);
//         }).exceptionally(throwable -> {
//             //可以感知异常，同时返回默认值
//             return 10;
//         });
//        Integer integer = future1.get();
//        System.out.println("main......end....."+integer);


        /**
         * 方法执行完后端处理
         */
//         CompletableFuture<Integer> future2 = CompletableFuture.supplyAsync(() -> {
//             System.out.println("当前线程：" + Thread.currentThread().getId());
//             int i = 10 / 0;
//             System.out.println("运行结果：" + i);
//             return i;
//             //handle 返回结果 异常
//         }, executor).handle((result,thr) -> {
//             if (result != null) {
//                 return result * 2;
//             }
//             if (thr != null) {
//                 System.out.println("异步任务成功完成了...结果是：" + result + "异常是：" + thr);
//                 return 0;
//             }
//             return 0;
//         });
//        System.out.println("future2返回值"+future2.get());


        /**
         * 线程串行化
         * 1、thenRunL：不能获取上一步的执行结果
         * 2、thenAcceptAsync：能接受上一步结果，但是无返回值
         * 3、thenApplyAsync：能接受上一步结果，有返回值
         *
         */
//        CompletableFuture<String> future3 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("当前线程：" + Thread.currentThread().getId());
//            int i = 10 / 2;
//            System.out.println("运行结果：" + i);
//            return i;
//        }, executor).thenApplyAsync(res -> {
//            System.out.println("任务2启动了..." + res);
//            return "Hello" + res;
//        }, executor);
//        System.out.println("future3返回值"+future3.get());
        /**
         * thenCombine：组合两个 future，获取两个 future 的返回结果，
         * 并返回当前任务的返回值
         * thenAcceptBoth：组合两个 future，获取两个 future 任务的返回结果，
         * 然后处理任务，没有返回值。
         * runAfterBoth：组合两个 future，不需要获取 future 的结果，
         * 只需两个 future 处理完任务后， 处理该任务。
         */

//        CompletableFuture<Integer> future4 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务1执行：" + Thread.currentThread().getId());
//            int i = 10 / 2;
//            System.out.println("任务1结束：" + i);
//            return i;
//        }, executor);
//        CompletableFuture<String> future5 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务2执行：" + Thread.currentThread().getId());
//            System.out.println("任务2结束：" );
//            return  "hello";
//        }, executor);

        //在前面两个任务执行后  第三个任务执行
//        runAfterBoth   组合任务 不能得到返回值
//        thenAcceptBoth 组合任务 得到返回值
//        thenCombine    组合任务 得到返回值  还能自己返回数据
//        future4.runAfterBothAsync(future5,()->{
//            System.out.println("任务3开始执行");
//        },executor);

//        System.out.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
//        future4.thenAcceptBothAsync(future5,(f1,f2)->{
//            System.out.println("任务3开始执行," +
//                    "获取第一个任务返回值f1"+f1 +
//                    "获取第二个任务返回值f2"+f2);
//        },executor);

//        CompletableFuture<String> future6 = future4.thenCombineAsync(future5, (f1, f2) -> {
//            System.out.println("任务3开始执行," +
//                    "获取第一个任务返回值f1" + f1 +
//                    "获取第二个任务返回值f2" + f2);
//            return "任务3开始执行," +
//                    "获取第一个任务返回值f1" + f1 +
//                    "获取第二个任务返回值f2" + f2+">>>>>>>>>> 任务三执行后返回值";
//        }, executor);
        //future6.get();




//           applyToEither：两个任务有一个执行完成，获取它的返回值，
//           处理任务并有新的返回值。
//           acceptEither：两个任务有一个执行完成，获取它的返回值，
//           处理任务，没有新的返回值。
//           runAfterEither：两个任务有一个执行完成，不需要获取 future 的结果，
//           处理任务，也没有返回值。


//        CompletableFuture<Object> future7 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务1执行：" + Thread.currentThread().getId());
//            int i = 10 / 2;
//            System.out.println("任务1结束：" + i);
//            return i;
//        }, executor);
//        CompletableFuture<Object> future8 = CompletableFuture.supplyAsync(() -> {
//            System.out.println("任务2执行：" + Thread.currentThread().getId());
//            try {
//                Thread.sleep(3000);
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            System.out.println("任务2结束：" );
//            return  "hello";
//        }, executor);



//        future7.runAfterEitherAsync(future8,()->{
//            System.out.println("任务3开始执行");
//        },executor);

           //需要相同的返回值类型  但是可以直接变成Object
//        future7.acceptEitherAsync(future8,(res)->{
//            System.out.println("任务3开始执行"+res);
//        },executor);
//
//            //如果要知道代码执行返回值 future.get();
//        future7.applyToEitherAsync(future8,(res)->{
//            System.out.println("任务3开始执行"+res);
//            return  "你好啊,我是任务3返回值";
//        },executor);

//        allOf：等待所有任务完成
//        anyOf：只要有一个任务完成


        CompletableFuture<String> futureImg = CompletableFuture.supplyAsync(() -> {
            System.out.println("查看商品的图片信息");
            return "hello.jpg";
        },executor);

        CompletableFuture<String> futureAttr = CompletableFuture.supplyAsync(() -> {
            try {
                Thread.sleep(3000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("查看商品的属性信息");
            return "黑色+256g";
        },executor);
        CompletableFuture<String> futureDesc = CompletableFuture.supplyAsync(() -> {
            System.out.println("查看商品的详情");
            return "华为手机";
        },executor);


        CompletableFuture<Void> allFuture = CompletableFuture.allOf(futureDesc, futureAttr, futureImg);

        //allFuture.get();


        System.out.println("main......end....." + futureDesc.get()+"sssssss+:" +futureAttr.get()+"ssssssss+"+futureImg.get());
        System.out.println("main......end....." + allFuture.get());

        //        CompletableFuture<Object> anyFuture = CompletableFuture.anyOf(futureDesc, futureAttr, futureImg);
        //        anyFuture.get();
        //System.out.println("main......end....." + anyFuture.get());





    }
}
